/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package upgmdendro.drawing;

import upgmdendro.drawing.drawables.DrawableDiagramObject;
import upgmdendro.drawing.drawables.DrawableScale;
import upgmdendro.drawing.drawables.Drawable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import upgmadendro.diagram.DiagramObject;
import upgmadendro.diagram.DiagramStructure;

/**
 *
 * @author psychollek
 */
public class PictureResolver {

    private ArrayList<Drawable> picture = new ArrayList<Drawable>();

    public ArrayList<Drawable> getPicture() {
        return picture;
    }

    public void resolveStructure(DiagramStructure ds) {

        picture = new ArrayList<Drawable>();

        picture.add(new DrawableScale(getConnectionValues(ds)));
        int basicObjectCount = getBasicObjectCount(ds);
        int w = GraphicParameters.getWidth();
        int c = (w-50)/(basicObjectCount-1);
        for (int i = 0; i < basicObjectCount; i++) {
            DiagramObject dobj = ds.getObjects().get(i);
            dobj.setPosition(40+(i*c));
            addBasicObject(dobj);
        }
        for (int i = basicObjectCount; i < ds.getObjects().size(); i++) {
            DiagramObject dobj = ds.getObjects().get(i);
            addConnectionObject(dobj,ds);
        }
    }

    private void addBasicObject(DiagramObject dobj) {
        Drawable d = new DrawableDiagramObject(dobj.getBorn(), dobj.getDead(), dobj.getPosition(), dobj.getName());
        picture.add(d);
    }

    private void addConnectionObject(DiagramObject dobj, DiagramStructure ds) {

        ArrayList<DiagramObject> objects = ds.getObjects();
        ArrayList<Integer> pos = new ArrayList<Integer>();

        DiagramObject start = null, end = null;

        for (Iterator<DiagramObject> it = objects.iterator(); it.hasNext();) {
            DiagramObject diagramObject = it.next();
            if (diagramObject == dobj) {
                break;
            }
            if (diagramObject.getDead() > dobj.getBorn()) {
                pos.add(diagramObject.getPosition());
            }
            if (diagramObject.getTurnsInto().equals(dobj)) {
                if (start == null) {
                    start = diagramObject;
                } else if (end == null) {
                    if (start.getPosition() > diagramObject.getPosition()) {
                        end = start;
                        start = diagramObject;
                    } else {
                        end = diagramObject;
                    }
                } else if (start.getPosition() > diagramObject.getPosition()) {
                    start = diagramObject;
                } else if (end.getPosition() < diagramObject.getPosition()) {
                    end = diagramObject;
                }
            }
        }

        for (Iterator<Integer> it = pos.iterator(); it.hasNext();) {
            Integer integer = it.next();
            if (integer > end.getPosition() || integer < start.getPosition()) {
                it.remove();
            }
        }
        pos.add(start.getPosition());
        pos.add(end.getPosition());

        Collections.sort(pos);

        Integer[] posA = pos.toArray(new Integer[0]);

        int bigStart = posA[0];
        int bigEnd = posA[0];

        for (int i = 1; i < posA.length; i++) {
            if (bigEnd - bigStart < posA[i] - posA[i - 1]) {
                bigStart = posA[i - 1];
                bigEnd = posA[i];
            }
        }

        dobj.setPosition(bigStart + ((bigEnd - bigStart) / 2));

        Drawable d = new DrawableDiagramObject(dobj.getBorn(), dobj.getDead(), dobj.getPosition(), start.getPosition(), end.getPosition());
        picture.add(d);
    }

    private int getBasicObjectCount(DiagramStructure ds) {

        int basicCount = 0;

        for (Iterator<DiagramObject> it = ds.getObjects().iterator(); it.hasNext(); basicCount++) {
            DiagramObject diagramObject = it.next();
            if (diagramObject.getBorn() > 0.0) {
                break;
            }
        }
        return basicCount;
    }

    private double[] getConnectionValues(DiagramStructure ds) {

        ArrayList<Double> d = new ArrayList<Double>();
        ArrayList<DiagramObject> objects = ds.getObjects();
        for (Iterator<DiagramObject> it = objects.iterator(); it.hasNext();) {
            DiagramObject dObj = it.next();
            if (!d.contains(new Double(dObj.getDead())) && dObj.getDead() != 1.0) {
                d.add(dObj.getDead());
            }
        }

        double[] retVal = new double[d.size()];
        for (int i = 0; i < retVal.length; i++) {
            retVal[i] = d.get(i);
        }
        return retVal;
    }
}
